#pragma once

#include "../Core/Ray.h"
#include "Texture.h"

namespace krt {

	struct Intersection;

	class Primitive;

	class KRT_API Material {
	public:
		Material(const Ref<Texture>& texture) :m_Tex(texture) {}

		virtual bool Scatter(const Ray& rayIn, const Intersection& dg, glm::vec3& attenuation, Ray& scattered)const = 0;

		virtual glm::vec3 Emitted(const glm::vec2& uv)const {
			return { 0.0f,0.0f,0.0f };
		}

	protected:
		Ref<Texture> m_Tex;
	};

	class KRT_API Lambertian : public Material {
	public:
		Lambertian(const Ref<Texture>& texture) :Material(texture) {}

		virtual bool Scatter(const Ray& rayIn, const Intersection& dg, glm::vec3& attenuation, Ray& scattered) const override;

	};

	class KRT_API Metal : public Material {
	public:
		Metal(const Ref<Texture>& texture) :Material(texture) {}

		virtual bool Scatter(const Ray& rayIn, const Intersection& dg, glm::vec3& attenuation, Ray& scattered) const override;
	};

	class KRT_API Dielectric : public Material {
	public:
		Dielectric(const Ref<Texture>& texture) :Material(texture) {}

		virtual bool Scatter(const Ray& rayIn, const Intersection& dg, glm::vec3& attenuation, Ray& scattered) const override;
	};

	class KRT_API Illumination : public Material {
	public:
		Illumination(const Ref<Texture>& texture, const glm::vec3& illum)
			:Material(texture), m_Illum(illum) {}

		virtual bool Scatter(const Ray& rayIn, const Intersection& dg, glm::vec3& attenuation, Ray& scattered) const override;

		virtual glm::vec3 Emitted(const glm::vec2& uv)const override {
			return m_Illum;
		}

	private:
		glm::vec3 m_Illum;

	};

}